home *** CD-ROM | disk | FTP | other *** search
- static char rcsid[] = "$Id: ranger1.c,v 1.1 1992/09/06 19:31:32 mike Exp $";
-
- /* $Log: ranger1.c,v $
- * Revision 1.1 1992/09/06 19:31:32 mike
- * Initial revision
- *
- */
-
- /* ranger1.c
- * ranger1:
- * This routine cruises through a list (sorted array of structures, one of
- * which is a pointer to a string) and picks a range that word falls in.
- * ???Blank ("") entries are skipped. Depends. Sometimes. I don't think
- * this part works all that well.
- * "" does NOT match "".
- *
- * Input:
- * start: A pointer to the string (char *) in the first structure of the
- * list. Yes, a pointer to a pointer.
- * blobs: The number of elements in the list. MUST be >= 0.
- * blobsize: sizeof() each structure in the list.
- * word: What we are looking for in the list.
- * Output:
- * matched: number of characters in word ALSO in at least one item in
- * list.
- * commonchars: given the range word falls in, these are the letters in
- * common in the range.
- * Returns: TRUE if word is in list else FALSE
- *
- * Fact: The number of letters in commonchars >= matched.
- *
- * Alg:
- * 1. find the max letters in word also in list (match-word)
- * 2. find the range of words in list that have match-word in them
- * 3. find max letters in common in range.
- * C Durland
- */
-
- /* idea for ranger3: pass in incit(): a routine to call when need to move
- * to next structure. Can be used for linked lists, etc. Note: can't use
- * incptr as a default unless want to pass in blobsize (or could have
- * blobsize double as offset). Note: If I do this, start will have to
- * point to the start of the structure and ranger3 will have to know the
- * offset of (char *). Could sleeze and subtract offset to find start of
- * structure.
- */
-
- /* Copyright 1989, 1990 Craig Durland
- * Distributed under the terms of the GNU General Public License.
- * Distributed "as is", without warranties of any kind, but comments,
- * suggestions and bug reports are welcome.
- */
-
- #include <const.h>
-
- /* increment a (char **) n bytes */
- #define incptr(ptr,n) (char**)((char *)ptr +n)
-
- ranger1(start,blobs,blobsize,word,matched,commonchars)
- char **start, *word, *commonchars; int *matched, blobs, blobsize;
- {
- char **a = NULL, **b = NULL, c, **ptr;
- register int j, len, s;
-
- *commonchars = '\0'; *matched = 0;
- if (0 == (len = strlen(word))) return FALSE; /* "" don't match nuthing */
- tryagain:
- for (j = blobs, ptr = start; j--; ptr = incptr(ptr,blobsize))
- {
- if (**ptr == '\0') continue; /* ignore blank entry */
- if ((s = strncmp(word,*ptr,len)) == 0) /* len characters match */
- if (a == NULL) a = ptr; /* the start of the matched words */
- else b = ptr; /* the end of the range */
- else if (s < 0) break; /* don't search entire list if don't have to */
- }
-
- if (a == NULL) /* no match in the list */
- if (len > 0) /* is there a match on the first n-1 characters? */
- { len--; goto tryagain; }
- else return FALSE; /* no possible match */
- *matched = len;
- if (b == NULL) /* only one instance of at least part of word */
- {
- strcpy(commonchars,*a);
- return (0 == strcmp(word,commonchars)); /* maybe a commplete match */
- }
-
- /* Have a range of words in list that match the first len chars of
- * word.
- * All words in range have their first len chars in common.
- * Now find the most characters that the words in range have in
- * common. This can be lots more than len.
- */
- for (len--; c = *(*a + len); len++) /* ???remember "" entries */
- for (ptr = incptr(a,blobsize); ptr <= b; ptr = incptr(ptr,blobsize))
- if (**ptr != '\0' && *(*ptr+len) != c) goto done; /* mismatch */
-
- done:
- strcpy(commonchars,*a); commonchars[len] = '\0';
- return FALSE;
- }
-